package com.dev.bbs.service.impl;

import static org.elasticsearch.index.query.QueryBuilders.matchQuery;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.SearchResultMapper;
import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;
import org.springframework.data.elasticsearch.core.aggregation.impl.AggregatedPageImpl;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.elasticsearch.core.query.SearchQuery;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONObject;
import com.dev.bbs.domain.BbsArticle;
import com.dev.bbs.repository.BbsArticleRepository;
import com.dev.bbs.service.IEsArticleService;

/**
 * 社区文章Service业务层处理
 *
 * @author ruoyi
 * @date 2019-09-17
 */
@Service
public class EsArticleServiceImpl implements IEsArticleService
{
    @Autowired
    private BbsArticleRepository  bbsArticleRepository;

    @Autowired
    private ElasticsearchTemplate elasticsearchTemplate;

    /**
     * 全文搜索社区文章列表
     *
     * @param keyword 关键词
     * @param pageNum 分页
     * @param pageSize 分页
     * @return 社区文章
     */
    @Override
    public Page<BbsArticle> selectBbsArticleEsList(String keyword, Integer pageNum, Integer pageSize)
    {
        // 排序
        String preTag = "<font color='#dd4b39'>";// google的色值
        String postTag = "</font>";
        // Sort sort = new Sort(Sort.Direction.DESC, "createTime");
        // Pageable pageable = PageRequest.of(pageNum, pageSize, sort);
        Pageable pageable = PageRequest.of(pageNum, pageSize);
        SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchQuery("title", keyword))
                .withHighlightFields(new HighlightBuilder.Field("title").preTags(preTag).postTags(postTag)).build();
        searchQuery.setPageable(pageable);
        // 高亮字段
        AggregatedPage<BbsArticle> page = elasticsearchTemplate.queryForPage(searchQuery, BbsArticle.class,
                new SearchResultMapper()
                {
                    @SuppressWarnings("unchecked")
                    @Override
                    public <T> AggregatedPage<T> mapResults(SearchResponse response, Class<T> clazz, Pageable pageable)
                    {
                        List<BbsArticle> list = new ArrayList<>();
                        for (SearchHit searchHit : response.getHits())
                        {
                            if (response.getHits().getHits().length <= 0)
                            {
                                return null;
                            }
                            BbsArticle bbsArticle = new BbsArticle();
                            HighlightField title = searchHit.getHighlightFields().get("title");
                            // 获取数据转成json，然后再转成bean
                            JSONObject data = new JSONObject();
                            Map<String, Object> map = searchHit.getSourceAsMap();
                            for (String key : map.keySet())
                            {
                                data.put(key, map.get(key));
                            }
                            bbsArticle = JSONObject.parseObject(data.toJSONString(), BbsArticle.class);
                            if (title != null)
                            {
                                bbsArticle.setTitle(title.fragments()[0].toString());
                            }
                            list.add(bbsArticle);
                        }
                        if (list.size() > 0)
                        {
                            return new AggregatedPageImpl<T>((List<T>) list, pageable,
                                    response.getHits().getTotalHits());
                        }
                        return null;
                    }
                });
        return page;
    }

    /**
     * 新增社区文章
     *
     * @param bbsArticle 社区文章
     * @return 结果
     */
    @Override
    public BbsArticle insertBbsArticle(BbsArticle bbsArticle)
    {
        return bbsArticleRepository.save(bbsArticle);
    }

    /**
     * 修改社区文章
     *
     * @param bbsArticle 社区文章
     * @return 结果
     */
    @Override
    public BbsArticle updateBbsArticle(BbsArticle bbsArticle)
    {
        return bbsArticleRepository.save(bbsArticle);
    }

    /**
     * 删除社区文章信息
     *
     * @param id 社区文章ID
     * @return 结果
     */
    public void deleteBbsArticleById(Long id)
    {
        bbsArticleRepository.deleteById(id);
    }
}
